<?php

// WebSocket 服务端
class WSServer
{
    private $ws;

    public function __construct($port = 9511)
    {
        $this->ws = new Swoole\WebSocket\Server('0.0.0.0', $port);
        // $this->ws = new Swoole\WebSocket\Server('0.0.0.0', $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
        $this->ws->set([
            // 'ssl_cert_file' => '',// SSL 证书路径
            // 'ssl_key_file' => '',// SSL KEY 路径
            'task_worker_num' => 4,// 设置异步任务的工作进程数量, 必须设置
        ]);
        $this->ws->on('Open', [$this, 'onOpen']);
        $this->ws->on('Message', [$this, 'onMessage']);
        $this->ws->on('Receive', [$this, 'onReceive']);
        $this->ws->on('Task', [$this, 'onTask']);
        $this->ws->on('Finish', [$this, 'onFinish']);
        $this->ws->on('Close', [$this, 'onClose']);
        $this->ws->start();
    }

    /**
     * 服务端连接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        $ws->push($request->fd, 'WS连接成功' . PHP_EOL);
    }

    /**
     * 服务端收到消息事件
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame)
    {
        echo 'WS收到客户端消息: ' . $frame->data;
        // 遍历所有客户端
        foreach ($ws->connections as $fd) {
            if ($fd == $frame->fd) {// 当前客户端连接标识
                $task_id = $ws->task([
                    'fd' => $fd,
                    'message' => '我: ' . $frame->data
                ]);
                $ws->push($fd, '我: ' . $frame->data);
            } else {// 其他客户端
                $ws->push($fd, '对方: ' . $frame->data);
            }
        }
    }

    /**
     * 异步任务, 在 task 进程中执行
     * @param $ws
     * @param $task_id
     * @param $reactor_id
     * @param $data
     */
    public function onTask($ws, $task_id, $reactor_id, $data)
    {
        var_dump(['flag' => 'task', 'task_id' => $task_id, 'message' => $data]);
        // 返回任务执行的结果
        // $ws->finish($data);
        return $data;
    }

    public function onFinish($ws, $task_id, $data)
    {
        var_dump(['flag' => 'finish', 'task_id' => $task_id, 'message' => $data]);
    }

    /**
     * 服务端关闭连接事件
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd)
    {
        echo 'WS客户端' . $fd . '关闭' . PHP_EOL;
        // $ws->close($fd);
    }
}